package com.randao.framework.common.exception;


import com.google.common.collect.ImmutableMap;
import com.randao.framework.common.model.response.CommonCode;
import com.randao.framework.common.model.response.ResponseResult;
import com.randao.framework.common.model.response.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


/**
 * @Author： ~Mr·Weng~
 * @CreateTime： 2019年-04月-24日  2:07
 * Look at the wine in the glass toast the rich first.
 */
@ControllerAdvice   //控制器增强类
public class ExceptionCatch {

    //记录日志
    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
    //定义map的builder对象，去构建上面的ImmutableMap，怎么构建，看最下面的静态代码块
    protected static ImmutableMap.Builder<Class<? extends Throwable>, ResultCode> builder = ImmutableMap.builder();
    //定义map，配置异常类型所对应的错误代码
    //谷歌提供的，线程安全，不可更改  Class<?extends Throwable> 异常类型，里面的是所有的异常类型都会集成Throwable，对应的错误代码是基于ResultCode
    private static ImmutableMap<Class<? extends Throwable>, ResultCode> EXCEPTION;

    //构建上面的ImmutableMap，添加系统异常到map（后面直接在这里往map里面添加异常即可）
    static {
        builder.put(NullPointerException.class, CommonCode.NO_QUERY_DATA);
    }

    @ExceptionHandler(CustomException.class)
    @ResponseBody   //因为要返回json格式数据到页面
    public ResponseResult customException(CustomException customException) {
        //记录日志
        LOGGER.error("catch Exception:{}", customException.getMessage());
        ResultCode resultCode = customException.getResultCode();
        return new ResponseResult(resultCode);
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody   //因为要返回json格式数据到页面
    public ResponseResult exception(Exception exception) {
        //记录日志
        LOGGER.error("catch Exception:{}", exception.getMessage());

        if (EXCEPTION == null) {
            EXCEPTION = builder.build();    //EXCEPTION构建成功
        }
        //从EXCEPTIONS中找异常类型所对应的错误代码，如果找到了将错误代码响应给用户，如果找不到给用户响应99999异常
        ResultCode resultCode = EXCEPTION.get(exception.getClass());
        if (resultCode != null) {  //找到了，返回自定义错误码
            return new ResponseResult(resultCode);
        } else {
            //没找到返回99999异常
            return new ResponseResult(CommonCode.SERVER_ERROR);

        }
    }

}
